package com.leiyun.lamekit;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.kvin.toolkit.utils.ProgressUtils;
import com.kvin.toolkit.utils.StringUtils;
import com.leiyun.lamelib.ringdroid.MarkerView;
import com.leiyun.lamelib.ringdroid.SamplePlayer;
import com.leiyun.lamelib.ringdroid.SoundFile;
import com.leiyun.lamelib.ringdroid.WaveformView;
import com.leiyun.lamelib.util.EncodeUtil;

import java.io.File;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int DISMISS = 0;
    public static final int SHOW = 1;
    public static final int PROGRESS = 3;
    public static final int SUCCESS = 4;
    public static final int PLAYING = 5;
    @BindView(R.id.m_wave)
    WaveformView mWave;
    @BindView(R.id.start_marker)
    MarkerView startMarker;
    @BindView(R.id.end_marker)
    MarkerView endMarker;
    @BindView(R.id.start_btn)
    Button startBtn;
    @BindView(R.id.start_et)
    EditText startEt;
    @BindView(R.id.play_btn)
    Button playBtn;
    @BindView(R.id.end_et)
    EditText endEt;
    @BindView(R.id.end_btn)
    Button endBtn;
    @BindView(R.id.load_btn)
    Button loadBtn;
    @BindView(R.id.convert_btn)
    Button convertBtn;
    @BindView(R.id.cut_btn)
    Button cutBtn;
    @BindView(R.id.add_btn)
    Button addBtn;
    @BindView(R.id.des_btn)
    Button desBtn;

    private Message mMsg;
    private File srcFile;
    private File outFile;

    private ProgressUtils mUtils;
    private SoundFile mSoundFile;
    private boolean isLoading;
    private long lastUpdateTime;

    private SamplePlayer mPlayer;
    private int startMills;
    private int endMills;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        init();
    }

    /**
     * init here
     */
    private void init() {
        this.convertBtn.setOnClickListener(this);
        this.loadBtn.setOnClickListener(this);
        this.cutBtn.setOnClickListener(this);

        this.playBtn.setOnClickListener(this);
        this.startBtn.setOnClickListener(this);
        this.endBtn.setOnClickListener(this);
        this.addBtn.setOnClickListener(this);
        this.desBtn.setOnClickListener(this);



        this.startMarker.setFocusable(true);
        this.startMarker.setFocusableInTouchMode(true);
//        this.startMarker.setMode(MarkerView.Mode.LEFT);
//        this.endMarker.setFocusable(true);
//        this.endMarker.setFocusableInTouchMode(true);
//        this.endMarker.setMode(MarkerView.Mode.RIGHT);
//
//        this.mWave.setOnWaveChangedListener(new WaveHandle());
//        this.mWave.setInTouchZoomMode(false);
//        this.startMarker.setWaveformView(mWave);
//        this.endMarker.setWaveformView(mWave);
//        MarkerMoveCompleteHandle mMoveHandle = new MarkerMoveCompleteHandle();
//        this.startMarker.setOnMoveCompleteListener(mMoveHandle);
//        this.endMarker.setOnMoveCompleteListener(mMoveHandle);

        setSoundFile();

        checkPer();

        initDialog();
    }


    /**
     * set sound file after reading completely
     */
    private void setSoundFile() {
        if (mSoundFile != null && !mWave.hasSoundFile()) {
            mWave.setSoundFile(mSoundFile);
            if (mPlayer == null) mPlayer = new SamplePlayer(mSoundFile);
        }
    }

    /**
     * init dialog
     */
    private void initDialog() {
        mUtils = ProgressUtils.getInstance(this);
        mUtils.setProgress(0);
        mUtils.setCanceledOnTouchOutside(false);
    }


    /**
     * request necessary permissions
     */
    private void checkPer() {
        String[] pers = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
        };

        if (!PermissionUtils.isPermitted(this, pers)) {
            PermissionUtils.requestPermission(this, pers, 5);
            return;
        }


    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 5) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                return;
            }
            this.finish();
        }
    }

    @Override
    public void onClick(View v) {
        if (v == convertBtn) {
            //convertFile();
            return;
        }
        if (v == loadBtn) {
            loadFile();
            return;
        }

        if (v == playBtn) {
            onPlay();
            return;
        }
        if (v == cutBtn) {
            //cut file here
            return;
        }

        if (v == startBtn) {
            //left select here
            startMills = mPlayer.getCurrentPosition();
            startEt.setText(StringUtils.parseTime(startMills));
//            mWave.setStartPosition(mWave.millisToPixels(startMills));
//            mWave.updateWaveform();
            onPlay();
            return;
        }

        if (v == endBtn) {
            //right select here
            endMills = mPlayer.getCurrentPosition();
            endEt.setText(StringUtils.parseTime(endMills));
//            mWave.setEndPosition(mWave.millisToPixels(endMills));
//            mWave.updateWaveform();
            onPlay();
        }
        if (v==addBtn){
            this.mWave.zoomIn();
            return;
        }
        if (v==desBtn){
            this.mWave.zoomOut();
            return;
        }

    }

    /**
     * on play
     */
    private synchronized void onPlay() {
        if (mPlayer == null) return;
        if (!mPlayer.isPlaying()) {
            mPlayer.setOnCompletionListener(new CompleteHandle());
//            mPlayer.setOnPlayingListener(new PlayingHandle());
            mPlayer.seekTo(startMills);
            mPlayer.start();
            playBtn.setText("pause");
            updateWave();
            return;
        }
        toPause();

    }

    /**
     * handle pause
     */
    private void toPause() {
        mPlayer.pause();
        mWave.setPlayback(-1);
//        mWave.setPlayingStatus(false);
        playBtn.setText("play");
    }

    /**
     * update wave
     */
    private synchronized void updateWave() {
        int now = mPlayer.getCurrentPosition();
//        int frames = mWave.millisToPixels(now);
//        mWave.setPlayback(frames);
//        resetDrawGap(frames - mWave.getMeasuredWidth() / 2);
//        mWave.setPlayingStatus(true);
    }

    /**
     * reset draw gaps
     */
//    private void resetDrawGap(int offset) {
//        int mOffsetGoal = offset;
//        if (mOffsetGoal + mWave.getMeasuredWidth() / 2 > mWave.getMaxPos())
////            mOffsetGoal = mWave.getMaxPos() - mWave.getMeasuredWidth() / 2;
//        if (mOffsetGoal < 0)
//            mOffsetGoal = 0;
//
//        int mOffset = mWave.getTouchOffset();
//        int offsetDelta = mOffsetGoal - mOffset;
//
//        if (offsetDelta > 10)
//            offsetDelta = offsetDelta / 10;
//        else if (offsetDelta > 0)
//            offsetDelta = 1;
//        else if (offsetDelta < -10)
//            offsetDelta = offsetDelta / 10;
//        else if (offsetDelta < 0)
//            offsetDelta = -1;
//        else
//            offsetDelta = 0;
//
//        mOffset += offsetDelta;
//
//        mWave.setTouchOffset(mOffset);
//    }

    /**
     * on complete listener
     */
    class CompleteHandle implements SamplePlayer.OnCompletionListener {

        @Override
        public void onCompletion() {
            toPause();
        }
    }

    /**
     * on Playing listener
     */
//    class PlayingHandle implements SamplePlayer.OnPlayingListener {
//        @Override
//        public void onPlaying() {
//            mHandler.sendEmptyMessage(PLAYING);
//        }
//    }

    /**
     * load files
     */
    private void loadFile() {
        mUtils.setTitle("reading...");
        isLoading = true;
        if (srcFile == null)
            srcFile = FileUtils.newFile(FileUtils.getStoragePath(), "sample5.wav");
        mUtils.show();
        readFile(srcFile.getAbsolutePath());
    }

    /**
     * read audio file
     */
    private void readFile(final String mediaPath) {
        ThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {

                try {
                    String[] components = mediaPath.split("\\.");
                    if (components.length < 2) {
                        mHandler.sendEmptyMessage(DISMISS);
                        return;
                    }
                    mSoundFile = SoundFile.create(srcFile.getAbsolutePath(), new LoadingFileHandle());
                } catch (Exception e) {
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(DISMISS);
                }
                mHandler.sendEmptyMessage(SUCCESS);
            }
        });
    }


    /**
     * handle loading progress
     */
    class LoadingFileHandle implements SoundFile.ProgressListener {
        @Override
        public boolean reportProgress(double fractionComplete) {
            long currentTime = System.nanoTime();
            if (currentTime - lastUpdateTime > 100) {
                mMsg = Message.obtain();
                mMsg.what = PROGRESS;
                mMsg.arg1 = (int) (mUtils.getMax() * fractionComplete);
                mHandler.sendMessage(mMsg);
                lastUpdateTime = currentTime;
            }
            return isLoading;
        }
    }


    /**
     * wave changed handle
     */
//    class WaveHandle implements WaveformView.OnWaveChangedListener {
//        @Override
//        public void onWaveChanged() {
//            startMarker.reLayout(mWave);
//            endMarker.reLayout(mWave);
//        }
//    }

    /**
     * marker move complete handle
     */
//    class MarkerMoveCompleteHandle implements MarkerView.OnMoveCompleteListener {
//        @Override
//        public void onMoveComplete(View v, int start, int end) {
//            toPause();
//
//            if (start != -1) startMills = mWave.pixelsToMillis(start);
//            endMills = mWave.pixelsToMillis(end);
//        }
//    }


    /**
     * convert file from wav to mp3
     */
    private void convertFile() {
//        srcFile = FileUtils.newFile(FileUtils.getStoragePath(), "sample-1.wav");
//        outFile = FileUtils.newFile(FileUtils.getStoragePath(), "chapter-1.mp3");

        if (!srcFile.exists()) {
            toast("srcFile is null");
            return;
        }

        if (!outFile.exists()) {
            toast("create file unsuccessfully");
            return;
        }

        //convert file in sub thread
        ThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                final EncodeUtil mUtil = EncodeUtil.init()
                        .numChannel(2)
                        .sampleRate(22050)
                        .bitRate(128000)
                        .mode(0)
                        .quality(2)
                        .vbrMode(5)
                        .build();

                mUtil.setOnProgressListener(new EncodeUtil.OnProgressListener() {

                    @Override
                    public void onProgress(int progress) {
                        Log.v("tag", "---------length=" + mUtil.getLength());
                        Log.v("tag", "--------recieve-p=" + progress);

                    }


                });

                mUtil.convertFromWav(srcFile.getAbsolutePath(), outFile.getAbsolutePath());

            }
        });
    }


    /**
     * simple toast
     *
     * @param msg
     */
    public void toast(String msg) {
        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
    }


    /**
     * handle msg here
     */
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int w = msg.what;
            if (w == DISMISS) {
                isLoading = false;
                mUtils.dismiss();
                return;
            }

            if (w == PROGRESS) {
                mUtils.setProgress(msg.arg1);
                return;
            }
            if (w == SUCCESS) {
                isLoading = false;
                mUtils.dismiss();
                setSoundFile();
                return;
            }

            if (w == PLAYING) {
                int now = mPlayer.getCurrentPosition();
//                int frames = mWave.millisToPixels(now);
//                mWave.setPlayback(frames);
//                mWave.updateWaveform();
//                LogUtils.v("------now="+now+"---end="+mWave.millisToPixels(endMills));
                if (now >= endMills) toPause();
                return;
            }
            String tag = msg.obj.toString();
            if (tag.equals("start")) {

                return;
            }
            if (tag.equals("progress")) {
                return;
            }
            if (tag.equals("finish")) {
                return;
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPlayer != null) {
//            mPlayer.recycle();
            mPlayer = null;
        }
    }
}
